
#ifndef __CMD_MNG_HPP__
#define __CMD_MNG_HPP__

#include "khan.hpp"
#include "vty.hpp"
#include "command2.hpp"
#include "command_mode.hpp"

class cmd_mng;
typedef boost::shared_ptr<cmd_mng> cmd_mng_ptr;

class cmd_mng : 
public boost::enable_shared_from_this<cmd_mng>,
private boost::noncopyable       
{
public:
    typedef std::map<std::string, command_mode_ptr> mode_map_t;
    typedef mode_map_t::iterator   mode_map_iterator;

    ~cmd_mng();

    static cmd_mng_ptr instance();

    bool find_mode(const std::string& modestr, command_mode_ptr& mode);
    bool add_mode(const std::string name, const std::string prompt, 
            bool is_auth = false);
    bool add_mode(const std::string name, const std::string prompt, 
            cmd_mode_ptr p, bool is_auth = false);
    bool add_command( const std::string mode, const std::string cmd, 
            const std::string help, ExcuteHandle function);

    bool describe_command(vty_ptr vty, const std::string& line, cmd_list_t& list, 
            bool child, bool& is_exec);
    bool excute_command(vty_ptr vty, const std::string& cmdline);

private:
    cmd_mng();

    bool find_tree_leaf(vty_ptr vty, const std::string& cmdline, cmd_list_t& retlist, 
            string_vector& args, bool is_child, bool& is_exec);
    bool make_cmdtree(cmd_ptr root, const std::string& cmdvec, 
            const std::string& helpvec, ExcuteHandle function);

    static cmd_mng_ptr _instance;
    static boost::mutex    _singletone_lock;

    cmd_mode_ptr _root_mode;

    mode_map_t  _mode_map;
    boost::mutex  _mode_lock;
    boost::mutex  _cmd_lock;
};

#endif
